package com.ledijiaoyu.autogate.serialport;

import android.util.Log;

import com.ledijiaoyu.autogate.base.AutoGatePacket;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;

import android_serialport_api.SerialPort;
import cn.dinkevin.xui.util.FileUtil;
import cn.dinkevin.xui.util.LogUtil;
import cn.dinkevin.xui.util.StringUtil;

/**
 * Create with Android Studio
 * Author: chengpengfei
 * Date: 2018/6/1
 * Time: 9:26 AM
 * Description:串口通道
 */
public class SerialPortTunnel {


    private String mSerialPortName;         // 串口号
    private int mSerialPortBaudRate;      // 波特率
    private SerialPort mSerialPort;
    private ReadThread mReadThread;
    private InputStream mInputStream;
    private OutputStream mOutputStream;
    private SerialPortReceiverListener mReceiverListener;


    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();

            while (!isInterrupted()) {
                int size;
                byte[] buffer = new byte[64];
                try {
                    if (mInputStream == null) {
                        return;
                    }

                    size = mInputStream.read(buffer);
                    byte[] result = new byte[size];
                    System.arraycopy(buffer,0,result,0,size);
                    if (size > 0) {
                        if(null != mReceiverListener)
                            mReceiverListener.onReceiveBuffer(result,size);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }

    /**
     * 构造器
     * @param mSerialPortName
     * @param mSerialPortBaudRate
     */
    public SerialPortTunnel(String mSerialPortName, int mSerialPortBaudRate) {
        this.mSerialPortName = mSerialPortName;
        this.mSerialPortBaudRate = mSerialPortBaudRate;
    }


    public void setReceiverListener(SerialPortReceiverListener listener){
        this.mReceiverListener = listener;
    }


    /**
     * 初始化串口数据
     */
    public void openSerialPort(){

        try {
            mSerialPort = getSerialPort();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();

            /* Create a receiving thread */
            mReadThread = new ReadThread();
            mReadThread.start();
            LogUtil.format_d("serial port initial ok");
        } catch (SecurityException | IOException | InvalidParameterException e) {
            LogUtil.format_e("serial port initial failed %s",e.getCause());
        }
    }


    protected SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {

        if (mSerialPort == null) {
            LogUtil.format_d("serial port SerialPort:%s baudRate:%s", mSerialPortName, mSerialPortBaudRate);

            /* Check parameters */
            if (StringUtil.isEmpty(mSerialPortName) || mSerialPortBaudRate == -1) {
                throw new InvalidParameterException();
            }

            /* Open the serial port */
            mSerialPort = new SerialPort(new File(mSerialPortName), mSerialPortBaudRate, 0);
        }
        return mSerialPort;
    }

    public void closeSerialPort() {
        if (mSerialPort != null) {
            if (null != mReadThread && !mReadThread.isInterrupted()) {
                mReadThread.interrupt();
                mReadThread = null;
            }
            try {
                FileUtil.closeStream(mOutputStream);
                FileUtil.closeStream(mInputStream);
                LogUtil.format_d("close serial port stream",null);
                mSerialPort.close();
            } catch (Exception e) {
                LogUtil.format_e("close serial port error",e.getCause());
            } finally {
                mSerialPort = null;
                mOutputStream = null;
                mInputStream = null;
            }
        }
    }

    public void write(byte[] buffer){
        try{
            LogUtil.format_d("write [Hex]:%s",StringUtil.byte2Hex(buffer));
            LogUtil.format_d("write [Char]:%s",StringUtil.char2String(StringUtil.byte2Char(buffer)));
            mOutputStream.write(buffer);
        }catch (Exception e){
            LogUtil.format_d("write to serial port %s", Log.getStackTraceString(e));
        }
    }
}

